import { BaseComp } from '../../../common/component/comp';
import { calc, cubicOut, cubicIn } from '../../../common/animation';

import events from './events';
import { z, layouts, color, paths } from './layout';

/**
 * 就是你在点开始抽奖的时候冒出的醒目组件
 */
class Tip extends BaseComp {
  baseTime = 0;
  spArrowAs = []; spArrowBs = [];

  constructor(args) {
    super(args.parent);
    this.zrender = args.zrender;
    this.zr = args.zr;

    this.layout = layouts.tips;
    this.activeTxLayout = this.layout.txBegin;
    this.x = this.layout.x;
    this.y = this.layout.y;
    
    this.on(events.PHASE_BEGIN, this.onBegin.bind(this));
    this.on(events.PHASE_READY, this.onReady.bind(this));
  }

  init() {
    const { layout, zr, zrender } = this;
    const [x, y] = this.absolutePos();
    const wAl = layout.mainBar.left;
    const wAr = wAl + layout.mainBar.width;
    const wBl = layout.subBar.left;
    const wBr = wBl + layout.subBar.width;

    this.spMainBar = new zrender.Polygon({
      position : [x, y],
      shape : {
        points: [
          [layout.offsetX + wAl, 0],
          [layout.offsetX + wAr, 0],
          [wAr, layout.height],
          [wAl, layout.height],
        ]
      },
      style: {
        fill: color.black,
      },
      z: z.tips.main,
    })
    this.spMainBar.hide();
    zr.add(this.spMainBar);
    this.spSubBar = new zrender.Polygon({
      position : [x, y],
      shape : {
        points: [
          [layout.offsetX + wBl, 0],
          [layout.offsetX + wBr, 0],
          [wBr, layout.height],
          [wBl, layout.height],
        ]
      },
      style: {
        fill: color.tip,
      },
      z: z.tips.sub,
    });
    this.spSubBar.hide();
    zr.add(this.spSubBar);

    // spArrowAs & spArrowBs
    for (let i = 0; i < 10; i++) {
      const spArrowA = zrender.path.createFromString(paths.tipsArrowA, {
        position : [-1, -1],
        style : { fill : color.tip, },
        z : z.tips.sub
      });
      spArrowA.hide();
      zr.add(spArrowA);
      this.spArrowAs.push(spArrowA);
      
      const spArrowB = zrender.path.createFromString(paths.tipsArrowB, {
        position : [-1, -1],
        style : { fill : color.tip, },
        z : z.tips.sub
      });
      spArrowB.hide();
      zr.add(spArrowB);
      this.spArrowBs.push(spArrowB);
    }

    // 弹幕开始
    this.spTxBeginFill = zrender.path.createFromString(paths.tipsBeginFill, {
      position : [x, y],
      style : { fill : '#FFF', },
      z : z.tips.textFill
    });
    this.spTxBeginFill.hide();
    zr.add(this.spTxBeginFill);
    this.spTxBeginStroke = zrender.path.createFromString(paths.tipsBeginStroke, {
      position : [x, y],
      style : { fill : '#000', },
      z : z.tips.textStroke
    });
    this.spTxBeginStroke.hide();
    zr.add(this.spTxBeginStroke);
  }

  onBegin() {
    this.spActiveFill = this.spTxBeginFill;
    this.spActiveStroke = this.spTxBeginStroke;
    this.activeTxLayout = this.layout.txBegin;
    this.readyAnimation();
  }

  onReady() {
    // this.spActiveFill = this.spTxBeginFill; // TODO
    // this.spActiveStroke = this.spTxBeginStroke; // TODO
    // this.activeTxLayout = this.layout.txBegin; // TODO
    // this.readyAnimation();
  }

  readyAnimation() {
    const { layout, activeTxLayout } = this;
    const [x, y] = this.absolutePos();
    this.baseTime = new Date().getTime();

    this.spMainBar.attr({ position: [x + layout.mainBar.srcX, y + layout.mainBar.srcY] });
    this.spMainBar.show();
    this.spSubBar.attr({ position: [x + layout.subBar.srcX, y + layout.subBar.srcY] });
    this.spSubBar.show();
    this.spArrowAs.forEach(sp => {
      sp.attr({ position: [-1, -1] });
      sp.show();
    });
    this.spArrowBs.forEach(sp => {
      sp.attr({ position: [-1, -1] });
      sp.show();
    });

    this.spActiveFill.attr({ position: [x + activeTxLayout.srcX1, y + activeTxLayout.srcY1] });
    this.spActiveStroke.attr({ position: [x + activeTxLayout.srcX1, y + activeTxLayout.srcY1] });
    this.spActiveFill.show();
    this.spActiveStroke.show();
  }

  tick() {
    if (this.baseTime != 0) {
      this.makeDirty();
    }
  }

  /**
   * 动画, 共 4s:
   * mainBar 出现: 0~0.5s  离开: 3.1~3.6s
   * subBar 出现: 0.2~0.7s  离开: 3.0~3.5s
   * arrowA/B 出现: 0.1~0.7s  离开: 3.3~3.9s
   * spActiveStroke/Fill 出现: 0.4~0.9s  离开: 3.0~3.5s
   */
  paint() {
    if (this.baseTime == 0) {
      return;
    }

    const { layout, activeTxLayout } = this;
    const [x, y] = this.absolutePos();
    const duration = new Date().getTime() - this.baseTime;

    // subBar
    if (duration < 500) {
      const spx = calc(x + layout.subBar.srcX, x, duration / 500, cubicOut);
      const spy = calc(y + layout.subBar.srcY, y, duration / 500, cubicOut);
      this.spSubBar.attr({ position: [spx, spy] });
    } else if (duration < 3000) {
      this.spSubBar.attr({ position: [x, y] });
    } else if (duration < 3500) {
      const spx = calc(x, x + layout.subBar.dstX, (duration - 3000) / 500, cubicIn);
      const spy = calc(y, y + layout.subBar.dstY, (duration - 3000) / 500, cubicIn);
      this.spSubBar.attr({ position: [spx, spy] });
    } else {
      this.spSubBar.hide();
    }

    // mainBar
    if (duration < 200) {
      this.spMainBar.attr({ position: [x + layout.mainBar.srcX, y + layout.mainBar.srcY] });
    } else if (duration < 700) {
      const spx = calc(x + layout.mainBar.srcX, x, (duration - 200) / 500, cubicOut);
      const spy = calc(y + layout.mainBar.srcY, y, (duration - 200) / 500, cubicOut);
      this.spMainBar.attr({ position: [spx, spy] });
    } else if (duration < 3100) {
      this.spMainBar.attr({ position: [x, y] });
    } else if (duration < 3600) {
      const spx = calc(x, x + layout.mainBar.dstX, (duration - 3100) / 500, cubicIn);
      const spy = calc(y, y + layout.mainBar.dstY, (duration - 3100) / 500, cubicIn);
      this.spMainBar.attr({ position: [spx, spy] });
    } else {
      this.spMainBar.hide();
    }

    // spArrowAs
    if (duration < 100) {
      // do-nothing
    } else if (duration < 700) {
      const delta = (duration - 100) / 600;
      const sx = x + layout.arrowA.x + calc(layout.arrowA.deltaX * -10, layout.arrowA.deltaX * 3, delta);
      const sy = y + layout.arrowA.y + calc(layout.arrowA.deltaY * -10, layout.arrowA.deltaY * 3, delta);
      this.spArrowAs.forEach((sp, i) => sp.attr({ position: [ sx - i * layout.arrowA.deltaX, sy - i * layout.arrowA.deltaY ]}));
    } else if (duration < 3300) {
      const delta = ((duration - 700) % 650) / 650;
      const sx = x + layout.arrowA.x + calc(layout.arrowA.deltaX * 3, layout.arrowA.deltaX * 4, delta);
      const sy = y + layout.arrowA.y + calc(layout.arrowA.deltaY * 3, layout.arrowA.deltaY * 4, delta);
      this.spArrowAs.forEach((sp, i) => sp.attr({ position: [ sx - i * layout.arrowA.deltaX, sy - i * layout.arrowA.deltaY ]}));
    } else if (duration < 3900) {
      const delta = (duration - 3300) / 600;
      const sx = x + layout.arrowA.x + calc(layout.arrowA.deltaX * 3, layout.arrowA.deltaX * 16, delta);
      const sy = y + layout.arrowA.y + calc(layout.arrowA.deltaY * 3, layout.arrowA.deltaY * 16, delta);
      this.spArrowAs.forEach((sp, i) => sp.attr({ position: [ sx - i * layout.arrowA.deltaX, sy - i * layout.arrowA.deltaY ]}));
    } else {
      this.spArrowAs.forEach(sp => sp.hide());
    }
    
    // spArrowBs
    if (duration < 100) {
      // do-nothing
    } else if (duration < 700) {
      const delta = (duration - 100) / 600;
      const sx = x + layout.arrowB.x + calc(layout.arrowB.deltaX * -10, layout.arrowB.deltaX * 3, delta);
      const sy = y + layout.arrowB.y + calc(layout.arrowB.deltaY * -10, layout.arrowB.deltaY * 3, delta);
      this.spArrowBs.forEach((sp, i) => sp.attr({ position: [ sx - i * layout.arrowB.deltaX, sy - i * layout.arrowB.deltaY ]}));
    } else if (duration < 3300) {
      const delta = ((duration - 700) % 650) / 650;
      const sx = x + layout.arrowB.x + calc(layout.arrowB.deltaX * 3, layout.arrowB.deltaX * 4, delta);
      const sy = y + layout.arrowB.y + calc(layout.arrowB.deltaY * 3, layout.arrowB.deltaY * 4, delta);
      this.spArrowBs.forEach((sp, i) => sp.attr({ position: [ sx - i * layout.arrowB.deltaX, sy - i * layout.arrowB.deltaY ]}));
    } else if (duration < 3900) {
      const delta = (duration - 3300) / 600;
      const sx = x + layout.arrowB.x + calc(layout.arrowB.deltaX * 3, layout.arrowB.deltaX * 16, delta);
      const sy = y + layout.arrowB.y + calc(layout.arrowB.deltaY * 3, layout.arrowB.deltaY * 16, delta);
      this.spArrowBs.forEach((sp, i) => sp.attr({ position: [ sx - i * layout.arrowB.deltaX, sy - i * layout.arrowB.deltaY ]}));
    } else {
      this.spArrowBs.forEach(sp => sp.hide());
    }

    // spActiveStroke/Fill
    if (duration < 400) {
      // do-nothing
    } else if (duration < 900) {
      const delta = (duration - 400) / 500;
      const sx = x + calc(activeTxLayout.srcX1, activeTxLayout.dstX1, delta);
      const sy = y + calc(activeTxLayout.srcY1, activeTxLayout.dstY1, delta);
      this.spActiveFill.attr({ position: [ sx, sy ]});
      this.spActiveStroke.attr({ position: [ sx, sy ]});
    } else if (duration < 3000) {
      const delta = (duration - 900) / 2100;
      const sx = x + calc(activeTxLayout.dstX1, activeTxLayout.srcX2, delta);
      const sy = y + calc(activeTxLayout.dstY1, activeTxLayout.srcY2, delta);
      this.spActiveFill.attr({ position: [ sx, sy ]});
      this.spActiveStroke.attr({ position: [ sx, sy ]});
    } else if (duration < 3500) {
      const delta = (duration - 3000) / 500;
      const sx = x + calc(activeTxLayout.srcX2, activeTxLayout.dstX2, delta);
      const sy = y + calc(activeTxLayout.srcY2, activeTxLayout.dstY2, delta);
      this.spActiveFill.attr({ position: [ sx, sy ]});
      this.spActiveStroke.attr({ position: [ sx, sy ]});
    } else {
      this.spActiveFill.hide();
      this.spActiveStroke.hide();
    }


    if (duration > 4000) {
      this.baseTime = 0;
    }
  }
}

export {
  Tip
};
